#include "run_cmd_base.h"
#include "events/common_log.h"
#include <sys/wait.h>

RunCmdBase::RunCmdBase(const char *cmd)
    : nAlloc(10)
    , nNum(1)
{
    argv = new char *[nAlloc + 1];
    argv[0] = (char *)cmd;
    argv[1] = NULL;
}

RunCmdBase::~RunCmdBase()
{
    delete [] argv;
}

void RunCmdBase::setProgramName(const char *cmd)
{
    argv[0] = (char *)cmd;
}

void RunCmdBase::appendStrings(const char *args, ...)
{
    va_list lists;

    va_start (lists, args);
    for (const char *arg = args; arg; arg = va_arg (lists, const char *))
    {
        if(nNum == nAlloc)
        {
            int    n = nAlloc;
            char **t;

            nAlloc += 10;
            t = new char* [nAlloc + 1];

            memcpy(t, argv, n * sizeof(char *));

            argv = t;
        }
        //GEN_Printf(LOG_DEBUG, "--%s--", argv[nNum-1]);
        //GEN_Printf(LOG_DEBUG, "[%d][%d] = %s", nAlloc, nNum, arg);
        argv[nNum++] = (char *)arg;
    }

    argv[nNum] = NULL;
    va_end (lists);
}

int RunCmdBase::wait4pid(pid_t pid)
{
    int status = 0;

    if (safe_waitpid(pid, &status, WUNTRACED) == -1)
    {
        GEN_Printf(LOG_ERROR, "wait pid: %X, %s", status, strerror(errno));
        return -1;
    }

    if (WIFEXITED(status))
    {
        return WEXITSTATUS(status);
    }

    if (WIFSIGNALED(status))
    {
        return WTERMSIG(status) + 0x180;
    }

    return 0;
}

pid_t RunCmdBase::safe_waitpid(pid_t pid, int *wstat, int options)
{
    pid_t r;

    do
    {
        r = waitpid(pid, wstat, options);
    } while ((r == -1) && (errno == EINTR));
    return r;
}

void RunCmdBase::profile()
{
    GEN_Printf(LOG_INFO, "seg num: %d, nAlloc=%d", nNum, nAlloc);
    for (int i = 0; i < nNum; ++i)
    {
        printf("%s ", argv[i]);
    }
    printf("\n\n");
}
